"""
认证相关的路由
包括登录、注册、令牌验证等
"""

from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import HTTPBearer
from pydantic import BaseModel, EmailStr
from sqlalchemy.ext.asyncio import AsyncSession

from src.auth import get_current_active_family_member
from src.crud import family_crud
from src.database import get_db
from src.models.family_model import FamilyMember, FamilyRole
from src.schemas.family_schema import FamilyMemberResponse
from src.security import (
    Token,
    create_token_response,
    get_password_hash,
    verify_password,
)

router = APIRouter(prefix="/auth", tags=["auth"])

security = HTTPBearer()


class LoginRequest(BaseModel):
    """登录请求模型"""

    username: str
    password: str


class LoginResponse(BaseModel):
    """登录响应模型"""

    access_token: str
    token_type: str
    family_member: FamilyMemberResponse


class RegisterRequest(BaseModel):
    """注册请求模型"""

    username: str
    email: EmailStr
    password: str
    full_name: str
    family_name: str


class ChangePasswordRequest(BaseModel):
    """修改密码请求模型"""

    current_password: str
    new_password: str


@router.post("/login", response_model=LoginResponse)
async def login(login_data: LoginRequest, db: AsyncSession = Depends(get_db)):
    """
    用户登录
    """
    # 查找用户
    family_member = await family_crud.get_family_member_by_username(
        db, username=login_data.username
    )
    if family_member is None:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="用户名或密码错误",
            headers={"WWW-Authenticate": "Bearer"},
        )

    # 验证密码
    if not verify_password(login_data.password, str(family_member.hashed_password)):
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="用户名或密码错误",
            headers={"WWW-Authenticate": "Bearer"},
        )

    # 检查用户是否活跃
    if not family_member.is_active:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST, detail="用户已被禁用"
        )

    # 创建令牌
    token = create_token_response(
        member_id=family_member.id,
        member_name=family_member.username,
        family_id=family_member.family_id,
        family_name=family_member.family_name,
        role=family_member.role,
    )

    # 返回响应
    return LoginResponse(
        access_token=token.access_token,
        token_type=token.token_type,
        family_member=FamilyMemberResponse.model_validate(family_member),
    )


@router.post("/register", response_model=FamilyMemberResponse)
async def register(register_data: RegisterRequest, db: AsyncSession = Depends(get_db)):
    """
    用户注册,注册的同时创建家庭。并且注册用户自动成为家庭的管理员,所以注册用户只能是管理员
    """
    # 检查用户名是否已存在
    existing_user = await family_crud.get_family_member_by_username(
        db, username=register_data.username
    )
    if existing_user is not None:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST, detail="用户名已存在"
        )

    # 检查邮箱是否已存在
    existing_email = await family_crud.get_family_member_by_email(
        db, email=register_data.email
    )
    if existing_email is not None:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST, detail="邮箱已存在"
        )
    # 检查家庭名是否存在
    existing_family = await family_crud.get_family_by_name(
        db, name=register_data.family_name
    )
    if existing_family:
        raise HTTPException(status_code=400, detail="家庭已经存在")
    # 创建家庭
    family = await family_crud.create_family(db, name=register_data.family_name)

    # 创建用户
    hashed_password = get_password_hash(register_data.password)

    family_member = await family_crud.create_family_member(
        db=db,
        username=register_data.username,
        email=register_data.email,
        hashed_password=hashed_password,
        full_name=register_data.full_name,
        role=FamilyRole.ADMIN,  # 注册用户默认为管理员
        family_id=family.id,
        is_active=True,
    )

    return FamilyMemberResponse.model_validate(family_member)


@router.post("/verify-token", response_model=FamilyMemberResponse)
async def verify_token_endpoint(
    current_user: FamilyMember = Depends(get_current_active_family_member),
):
    """
    验证令牌并返回用户信息
    """
    return FamilyMemberResponse.model_validate(current_user)


@router.post("/refresh-token", response_model=Token)
async def refresh_token(
    member: FamilyMember = Depends(get_current_active_family_member),
):
    """
    刷新访问令牌
    """
    token = create_token_response(
        member_id=member.id,
        member_name=member.username,
        family_id=member.family_id,
        family_name=member.family_name,
        role=member.role,
    )
    return token


@router.post("/change-password")
async def change_password(
    change_data: ChangePasswordRequest,
    current_family_member: FamilyMember = Depends(get_current_active_family_member),
    db: AsyncSession = Depends(get_db),
):
    """
    修改密码
    """
    # 验证当前密码
    if not verify_password(
        change_data.current_password, str(current_family_member.hashed_password)
    ):
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST, detail="当前密码错误"
        )

    # 更新密码
    new_hashed_password = get_password_hash(change_data.new_password)
    await family_crud.update_family_member(
        db=db,
        member_id=int(current_family_member.id),
        hashed_password=new_hashed_password,
        family_id=current_family_member.family_id,
    )

    return {"message": "密码修改成功"}


@router.post("/logout")
async def logout(
    current_family_member: FamilyMember = Depends(get_current_active_family_member),
):
    """
    用户登出
    """
    # 在实际应用中,可以将令牌加入黑名单
    # 这里只是返回成功消息
    return {"message": "登出成功"}
